/*
 * @Author: 吴世扬 18368095041@163.com
 * @Date: 2025-02-11 16:37:05
 * @LastEditors: 吴世扬 18368095041@163.com
 * @LastEditTime: 2025-02-26 08:32:50
 * @FilePath: /vue3-admin-server/src/admin/v1/auth/login.controller.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

import {
    Controller,
    Get,
    Res,
    Body,
    Post,
    Req,
    UseGuards
} from '@nestjs/common';
// import { Response, Request } from 'express';
import { create } from 'svg-captcha'; // 修改: 使用 svg-captcha 库
import { createCipheriv, createDecipheriv, randomBytes } from 'crypto';

import { LoginByPasswordDTO } from 'src/common/dto/login';
import { AuthGuard } from 'src/guards/auth.guard';

import { UserService } from 'src/shareModules/auth/auth.module';
import { ResponseService } from 'src/shareModules/common/common.module';

const algorithm = 'aes-256-cbc'; // 使用的加密算法
const key = randomBytes(32); // 生成一个32字节的密钥
const iv = randomBytes(16); // 生成一个16字节的初始化向量

@Controller('admin/api/v1/login')
export class LoginController {
    constructor(
        private readonly responseService: ResponseService,
        private readonly userService: UserService
    ) {}

    @Post('login')
    async login(
        @Body() loginDTO: LoginByPasswordDTO,
        @Req() req: HwRequest
    ): Promise<VO.ResultVO<string>> {
        if (req.cookies?.captchaSession === undefined)
            return this.responseService.error('验证码失效');

        const captchaText = this.decryptCaptchaText(
            req.cookies?.captchaSession.toUpperCase()
        );
        if (captchaText !== loginDTO.captcha.toUpperCase())
            return this.responseService.error('验证码错误');

        const result = await this.userService.loginByPassword(loginDTO);
        if (result === null) {
            return this.responseService.error('账号或密码错误');
        }

        return this.responseService.success('登录成功', result);
    }

    @Get('captcha')
    readCaptcha(@Res() res: HwResponse): void {
        const captcha = create({ color: true }); // 使用 svg-captcha 生成验证码
        const cipher = createCipheriv(algorithm, Buffer.from(key), iv); // 创建加密器
        let encrypted = cipher.update(
            captcha.text.toUpperCase(),
            'utf8',
            'hex'
        );
        encrypted += cipher.final('hex'); // 加密验证码文本
        res.cookie('captchaSession', encrypted, {
            httpOnly: true,
            maxAge: 60 * 60 * 1000
        }); // 将加密后的验证码文本绑定到cookie中
        res.set('Content-Type', 'image/svg+xml'); // 设置响应头
        res.send(captcha.data); // 发送图片
    }

    /**
     * 解密captchaSession
     * @param encryptedText
     * @returns
     */
    decryptCaptchaText(encryptedText: string): string {
        const decipher = createDecipheriv(algorithm, Buffer.from(key), iv); // 创建解密器
        let decrypted = decipher.update(encryptedText, 'hex', 'utf8');
        decrypted += decipher.final('utf8'); // 解密验证码文本
        return decrypted;
    }

    @Get('captcha')
    @UseGuards(AuthGuard)
    async logout(@Req() req: HwRequest) {
        if (req.tokenPayload === undefined)
            return this.responseService.success();
        await this.userService.logout(req.tokenPayload.id);
        return this.responseService.success();
    }
}
